#include "app_mqtt.h"
#include "MQTTClient.h"
#include "string.h"
#include "log.h"

// MQTT客户端
static MQTTClient client;
// MQTT客户端连接选项
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
// MQTT客户端要发送的消息
static MQTTClient_message pubmsg = MQTTClient_message_initializer;

// 失联回调
static void app_mqtt_lost_callback(void *context, char *cause)
{
    log_error("MQTTClient_lost_callback: %s", cause);
}

// 声明一个回调函数用于注册一个接受数据的回调函数
static int (*recv_callback)(char *data);

// 收到数据回调
static int app_mqtt_receive_callback(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    log_info("MQTTClient_receive_callback:%s", topicName);
    int ret = recv_callback((char *)message->payload);
    int status = 1;
    if (ret != 0)
    {
        log_error("接收数据处理失败：%s", message->payload);
        status = 0; //失败
    }
    return status;//成功是1,失败是0
}

// 发送成功回调
static void app_mqtt_sent_callback(void *context, MQTTClient_deliveryToken dt)
{
    log_info("MQTTClient_sent_success...");
}

int app_mqtt_init(void)
{
    // 1.创建一个MQTT客户端
    int ret = MQTTClient_create(&client, MQTT_ADDR, MQTT_CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        perror("MQTTClient create...");
        return -1;
    }

    // 2.设置回调函数（失联、收到数据、发送成功）
    ret = MQTTClient_setCallbacks(client, NULL, app_mqtt_lost_callback,
                                  app_mqtt_receive_callback, app_mqtt_sent_callback);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        perror("MQTTClient setCallbacks...");
        return -1;
    }

    // 3.连接客户端
    ret = MQTTClient_connect(client, &conn_opts);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        perror("MQTTClient connect...");
        MQTTClient_destroy(&client);
        return -1;
    }
    // 4.订阅主题
    ret = MQTTClient_subscribe(client, MQTT_RECV_TOPIC, 1);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        perror("MQTTClient subscribe...");
        // 销毁客户端
        app_mqtt_destroy();
        return -1;
    }
    return 0;
}

int app_mqtt_send(char *data)
{
    pubmsg.payload = data;
    pubmsg.payloadlen = strlen(data);
    int ret = MQTTClient_publishMessage(client, MQTT_SEND_TOPIC, &pubmsg, NULL);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        perror("MQTTClient publishMessage...");
        return -1;
    }
    return 0;
}

int app_mqtt_register_recv_callback(int (*callback)(char *data))
{
    recv_callback = callback;
    return 0;
}

void app_mqtt_destroy(void)
{
    MQTTClient_disconnect(client, 0);

    MQTTClient_destroy(&client);

    log_info("MQTTClient destroy...");
}
